/**
 * @file TEST_ucos_heap.c
 * @author Linquan  
 * @brief 
 *          创建：小容量（每块32字节）、中容量（每块128字节）两个内存池
 *          每个内存池给了5个块
 * 
 * @version 1.0
 * @date 2024-06-13
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#include "app_config.h"
#include "../../middle/serve/memory_mange/memory_mang_conf.h"

#if (TEST_MEMORY_TEST_UCOS_HEAP && UCOS__HEAP)


#include "../../middle/serve/memory_mange/uCOS3_heap.h"
#include <stdio.h>


/* 定义一个存储区，如果有不同大小的需要，就定义多个块大小的存储区 */

OS_MEM mem_region_small;
OS_MEM mem_region_middle;


/* 定义存储区中存储块数量 */
#define SMALE_MEM_NUM		5
#define MID_MEM_NUM		    5


/*  定义每个存储块大小
 *  由于一个指针变量占用4字节所以块的大小一定要为4的倍数 */
/*  而且必须大于一个指针变量(X64 = 8字节, X32 = 4字节)占用的空间,否则的话存储块创建不成功!!! */
#define SMALE_MEMBLOCK_SIZE	32  
#define MID_MEMBLOCK_SIZE	128  

/* 定义存储区的内存池，使用内部RAM */
CPU_INT08U Middle_RamMemp[MID_MEM_NUM][MID_MEMBLOCK_SIZE];
CPU_INT08U smale_RamMemp[MID_MEM_NUM][MID_MEMBLOCK_SIZE];

void err_log(int num,OS_MEM_ERR err)
{
     if(err != OS_ERR_NONE) //内存块不足
    {
        printf("number :%d, Erro occur ! err:%d \n",num, err);
    }
}

void ucos_heap_test()
{
    OS_MEM_ERR err;
    CPU_INT08U *middle_buf,*small_buf;
    CPU_INT08U *buf1, *buf2, *buf3, *buf4, *buf5;
 
    CPU_INT08U i;

/* 1、创建内存区 */


    /* 创建小内存池 */
    umem_block_create((OS_MEM*	)&mem_region_small,
				(CPU_CHAR*	)"Internal Mem",
				(void*		)&smale_RamMemp[0][0],
				(OS_MEM_QTY	)SMALE_MEM_NUM,
				(OS_MEM_SIZE)SMALE_MEMBLOCK_SIZE,
				(OS_MEM_ERR*	)&err);
    err_log(__LINE__,err);

    /* 创建中等内存池 */
    umem_block_create((OS_MEM*	)&mem_region_middle,
				(CPU_CHAR*	)"Internal Mem",
				(void*		)&Middle_RamMemp[0][0],
				(OS_MEM_QTY	)MID_MEM_NUM,
				(OS_MEM_SIZE)MID_MEMBLOCK_SIZE,
				(OS_MEM_ERR*	)&err);
    err_log(__LINE__,err);

/* 2、申请内存块 */

    /* 小内存申请 */
    small_buf  = umem_block_malloc((OS_MEM*)&mem_region_small, (OS_MEM_ERR*)&err);
    err_log(__LINE__,err);

    if(err == OS_ERR_NONE) //内存申请成功
    {
        printf("small_buf add :%p\r\n", (small_buf));
        printf("Memory Get success!  ");
        small_buf[0]  = 0;
        small_buf[13] = 3;
        small_buf[15] = 5;
        small_buf[28] = 8;
        small_buf[30] = 30;
        printf("small_buf :%s \n",small_buf[0]); 
        printf("small_buf :%d \n",small_buf[13]);
        printf("small_buf :%d \n",small_buf[15]); 
        printf("small_buf :%d \n",small_buf[30]); 
    }
    if(err == OS_ERR_MEM_NO_FREE_BLKS) //内存块不足
    {
        printf("Memory Get FAIL!  \n");
    }

    /* 中等内存申请 */
    middle_buf = umem_block_malloc((OS_MEM*)&mem_region_middle, (OS_MEM_ERR*)&err);
    err_log(__LINE__,err);

    if(err == OS_ERR_NONE) //内存申请成功
    {
        printf("middle_buf add :%p\r\n", (middle_buf));
        printf("Memory Get success!  ");
        middle_buf[0]  = 1;
        middle_buf[30] = 3;
        middle_buf[50] = 5;
        middle_buf[80] = 7;
        middle_buf[99] = 9;
        printf("middle_buf :%s \n",middle_buf); 
        printf("middle_buf :%d \n",middle_buf[0]);
        printf("middle_buf :%d \n",middle_buf[30]); 
        printf("middle_buf :%d \n",middle_buf[99]); 
    }
    if(err == OS_ERR_MEM_NO_FREE_BLKS) //内存块不足
    {
        printf("Memory Get FAIL!  \n");
    }

/* 3、释放内存块 */

    /* 释放小内存块*/
    if(small_buf != NULL) //internal_buf不为空就释放内存
    {
        umem_block_free((OS_MEM*	)&mem_region_small,		//释放内存
                    (void*		)small_buf,
                    (OS_MEM_ERR* 	)&err);
        printf("--small_buf release add :%p\r\n", (small_buf));
        printf("Memory Free success!  \n ");
    }

    /* 释放中等内存块*/
    if(middle_buf != NULL) //internal_buf不为空就释放内存
    {
        umem_block_free((OS_MEM*	)&mem_region_middle,		//释放内存
                    (void*		)middle_buf,
                    (OS_MEM_ERR* 	)&err);
        printf("--middle_buf release add :%p\r\n", (middle_buf));
        printf("Memory Free success!  \n ");
    }

/* 4、批量多次申请 *************************************************************/

    #define BUFF(i)     buf##i
    printf("_______muti application______________  \n ");

    for(i=0; i<2; i++)
    {
        BUFF(1) = umem_block_malloc((OS_MEM*)&mem_region_middle, (OS_MEM_ERR*)&err);
        err_log(__LINE__,err);
        BUFF(2) = umem_block_malloc((OS_MEM*)&mem_region_middle, (OS_MEM_ERR*)&err);
        err_log(__LINE__,err);
        BUFF(3) = umem_block_malloc((OS_MEM*)&mem_region_middle, (OS_MEM_ERR*)&err);
        err_log(__LINE__,err);
        BUFF(4) = umem_block_malloc((OS_MEM*)&mem_region_middle, (OS_MEM_ERR*)&err);
        err_log(__LINE__,err);
        BUFF(5) = umem_block_malloc((OS_MEM*)&mem_region_middle, (OS_MEM_ERR*)&err);
        err_log(__LINE__,err);

        if(err == OS_ERR_NONE) //内存申请成功
        {
            printf("BUFF(1) add :%p\r\n", (BUFF(1)));
            printf("BUFF(2) add :%p\r\n", (BUFF(2)));
            printf("BUFF(3) add :%p\r\n", (BUFF(3)));
            printf("BUFF(4) add :%p\r\n", (BUFF(4)));
            printf("BUFF(5) add :%p\r\n", (BUFF(5)));
            printf("Memory Get success!  \n");
            BUFF(5)[0]  = 11;           
            BUFF(5)[99] = 99;
            
            printf("BUFF(5) buf :%d \n",BUFF(5)[0]); 
            printf("BUFF(5) buf :%d \n",BUFF(5)[99]); 
        }
        if(err == OS_ERR_MEM_NO_FREE_BLKS) //内存块不足
        {
            printf("Memory Get FAIL! MAX num: %d \n",mem_region_middle.NbrMax);
            printf("Memory Get FAIL! NbrFree: %d \n",mem_region_middle.NbrFree);
        }

        if(BUFF(5) != NULL) //internal_buf不为空就释放内存
        {
            umem_block_free((OS_MEM*	)&mem_region_middle,		//释放内存
                        (void*		)BUFF(5),
                        (OS_MEM_ERR* 	)&err);
            printf("BUFF(5) release add :%p\r\n", (BUFF(5)));
            printf("Memory Put success!   \n");
        }

    }
}
EXPORT_Lv6_APP_SINGLE(ucos_heap_test,NULL);


#endif